package schoolsource.util;

public class Encrypter {

    private static String valids = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890!@$^&()_-+={[}]|:;?><,.";
    private static char validChars[] = valids.toCharArray();

    private Encrypter(String keyFileName) {

    }

    public static void main(String args[]) {
        if (args.length != 2 || (!"e".equals(args[0]) && !"d".equals(args[0]))) {
//            System.out.println("Usage: [e | d] \"string\"");
        }
        else if (!isValidString(args[1])) {
//            System.out.println( args[1] + " contains illegal characters.");
        }
        else {
            if ("e".equals(args[0])) {
//                System.out.println("encrypting " + args[1]);
//                System.out.println(encrypt(args[1]));
            }
            else {
//                System.out.println("decrypting " + args[1]);
//                System.out.println(decrypt(args[1]));
            }
        }
    }

    public static String encrypt(String s) {
        StringBuffer output = new StringBuffer();
        char group[] = new char[3];

        int total1 = 0;
        int total2 = 0;
        int total3 = 0;
        for (int i = 0; i < s.length(); i++) {
            switch (s.charAt(i) % 3) {
                case 0: total1 += s.charAt(i)*3/2;
                        total2 += validChars[(s.charAt(i)%validChars.length)];
                        total3 += total1%s.charAt(i) + 2*total2%s.charAt(i);
                        break;
                case 1: total2 += s.charAt(i)*5/3;
                        total3 += validChars[(s.charAt(i)%validChars.length)];
                        total1 += total3%s.charAt(i) + 2*total2%s.charAt(i);
                        break;
                case 2: total3 += s.charAt(i)*7/5;
                        total1 += validChars[(s.charAt(i)%validChars.length)];
                        total2 += total1%s.charAt(i) + 2*total3%s.charAt(i);
                        break;
            }
        }


        group[0] = validChars[total1%validChars.length];
        group[1] = validChars[total2%validChars.length];
        group[2] = validChars[total3%validChars.length];
//        group[0] = validChars[(int) (Math.random() * validChars.length)];
//        group[1] = validChars[(int) (Math.random() * validChars.length)];
//        group[2] = validChars[(int) (Math.random() * validChars.length)];
        output.append(new String(group));
        char first;
        int offset;
        int rndvar;
        for (int i = 0; i < s.length(); i++) {
            first = group[(group[0] + group[1] + group[2] + 1) % 3]; // mod of ascii values
            offset = first % 3;                                      // mod of ascii values
            group = new char[3];
            group[offset] = validChars[(int) (first%validChars.length)];
            int second = (int) ((group[offset]*35/3)%validChars.length);
//            group[offset] = validChars[(int) (Math.random() * validChars.length)];
//            int second = (int) (Math.random() * validChars.length);
            group[(offset == 2) ? 1 : 2] = validChars[second];

            for (int loc = 0;loc < validChars.length; loc++) {
                if (s.charAt(i) == validChars[loc]) {
                    //group[((offset % 2) + offset + 1) % 3] = validChars[(loc + offset) % validChars.length];
                    group[((offset % 2) + offset + 1) % 3] = validChars[(loc + second) % validChars.length];
                    break;
                }
            }
            // junk
            output.append(new String(group));
        }
        // add junk?
        return output.toString();
    }

    public static String decrypt(String s) {
        StringBuffer output = new StringBuffer();
        char input[] = s.toCharArray();
        char first;
        int offset;
        int second = 0;
        for (int i = 0; i < input.length - 3;) {
            first = input[((input[i++] + input[i++] + input[i++] + 1) % 3) + i - 3];
            offset = (first % 3);
            for (int loc = 0;loc < validChars.length; loc++) {
                if (input[i + ((offset == 2) ? 1 : 2)] == validChars[loc]) {
                    second = loc; // location of offset val in array
                    break;
                }
            }
            for (int loc = 0;loc < validChars.length; loc++) {
                if ((input[(i + (((offset % 2) + offset + 1) % 3))]) == validChars[loc]) {
                    output.append((char) (validChars[((loc - second) < 0) ? (loc - second + validChars.length) : (loc - second) ]));
                    break;
                }
            }
        }
        return output.toString();
    }

    public static boolean isValidString(String input) {
        for (int i = 0; i < input.length(); i++) {
            for (int j = 0; j < validChars.length; j++) {
                if (input.charAt(i) == validChars[j]) {
                    break;
                }
                else if (j == (validChars.length - 1)) {
//                    System.out.println(input.charAt(i) + " is not a legal character");
                    return false;
                }
            }
        }
        return true;
    }
}

